﻿using System;
using Framework.MVC;
using Log.Model;
using Extention.Model;
using Account.Model;
using Account.Model.Behavior;
using Config.Model;
using System.Collections.Generic;
using Framework.Common.Entry;
using Framework.Extention.Billing;
using Account.IService.Entry;
using Identity.IService.Entry;
using Extention.Model.Behavior;
using Common.IService.Entry;
using Framework.MVVM.Model;
using Common.IService;
using Common.Service;
using Log.IService;
using Log.Service;
using Extention.IService;
using Extention.Service;
using Config.IService;
using Config.Service;


namespace FrontCenter.Models
{
    [ServiceAttribute(typeof(IConfigService), typeof(ConfigService), "Instance")]
    [ServiceAttribute(typeof(Account.IService.IAccountService), typeof(Account.Service.AccountService), "Instance")]
    [ServiceAttribute(typeof(IOrderService), typeof(OrderService), "Instance")]
    [ServiceAttribute(typeof(ILogService), typeof(LogService), "Instance")]
    [ServiceAttribute(typeof(ICodeService), typeof(CodeService), "Instance")]
    public class ConfirmOrderModel : AsyncModelBase, IWriteLog, IGetOrder, IGetAccountByCode, IGetConfig<IDictionary<string, KeyValueEntry<string, decimal>>>, IGetConfig<IDictionary<string, KeyValueEntry<string, string>>>, IGetConfig<IBilling>
    {
        #region Field

        private const string m_order_error = "cforder00";
        private const string m_order_complete = "cforder01";
        private const string m_account_empty = "cforder02";
        private const string m_account_error = "cforder03";
        private const string m_account_complete = "cforder04";
        private const string m_config_source_error = "cforder05";
        private const string m_config_source_complete = "cforder06";
        private const string m_config_type_error = "cforder07";
        private const string m_config_type_complete = "cforder08";
        private const string m_config_billing_error = "cforder09";
        private const string m_config_billing_complete = "cforder10";
        

        private const string m_resource_user = "u000";

        private const string m_order = "order";
        private const string m_account = "account";

        private const string m_exchange = "exchange";

        private const string m_split = ";";

        private const string m_type_config = "data:order:type";
        private const string m_source_config = "data:order:source";

        #endregion Field

        #region Property

        public string Source { get; set; }

        public string Type { get; set; }

        #endregion Property

        #region AsyncModelBase

        protected override void OnInit(Type type)
        {
            OnBeginRequest();
            this.GetOrder(m_order_error, m_order_complete);
        }

        #endregion AsyncModelBase

        #region IWriteLog

        public void OnWriteLogComplete(string eventCode)
        {
            OnEndRequest();
        }

        public void OnWriteLogError(string eventCode)
        {
            OnEndRequest();
        }

        #endregion IWriteLog

        #region IGetOrder

        public string OrderCode { get; set; }

        public string OrderSource { get; set; }

        public void OnGetOrderComplete(string key, Extention.IService.Entry.OrderEntry entry)
        {
            OnComplete(m_order, entry);
            OnBeginRequest();
            AccountCode = entry.owner;
            this.GetAccount("Default", m_account_error, m_account_complete);
            OnBeginRequest();
            amount = entry.amount;
            ConfigName = m_source_config;
            this.GetConfig<IDictionary<string, KeyValueEntry<string, decimal>>>(m_config_source_error, m_config_source_complete);
            this.Log(key, new SourceEntry<Extention.IService.Entry.OrderEntry> { source = Source, data = entry });
        }

        public void OnGetOrderError(string key)
        {
            this.Log(key, new SourceEntry<Extention.IService.Entry.OrderEntry> { source = Source, data = new Extention.IService.Entry.OrderEntry { orderCode = OrderCode, sourceCode = OrderSource } });
        }

        #endregion IGetOrder

        #region IGetAccountByCode

        public string AccountCode { get; set; }

        public void OnGetAccountByCodeComplete(string key, string name)
        {
            OnComplete(m_account, name);
            this.Log(key, name);
        }

        public void OnGetAccountByCodeError(string key)
        {
            this.Log(key, Source + m_split + AccountCode);
        }

        #endregion IGetAccountByCode

        #region IGetConfig Billing Source

        public void OnGetConfigComplete(string key, IDictionary<string, KeyValueEntry<string, decimal>> entry)
        {
            if (entry.ContainsKey(OrderSource))
            {
                OnBeginRequest();
                OnComplete(m_exchange, entry[OrderSource].value);
                m_subject = entry[OrderSource].key;
                ConfigName = m_type_config;
                this.GetConfig<IDictionary<string, KeyValueEntry<string, string>>>(m_config_type_error, m_config_type_complete);
            }

            this.Log(key, Source + m_split + OrderCode + m_split+OrderSource);
        }

        #endregion IGetConfig Billing Source

        #region IGetConfig Billing Type

        public void OnGetConfigComplete(string key, IDictionary<string, KeyValueEntry<string, string>> entry)
        {
            if (entry.ContainsKey(Type))
            {
                OnBeginRequest();
                ConfigName = entry[Type].key;
                m_billing_type = entry[Type].value;
                this.GetConfig<IBilling>(m_config_billing_error, m_config_billing_complete);
            }
            this.Log(key, Source + m_split + OrderCode + m_split + OrderSource);

        }

        #endregion IGetConfig Billing Type

        #region IGetConfig Billing

        private decimal amount = 0;
        private string m_subject = string.Empty;
        private string m_billing_type = string.Empty;

        private const string m_order_name = "order";
        private const string m_amount_name = "amount";
        private const string m_subject_name = "subject";
        private const string m_type_name = "type";
        private const string m_resource_name = "resource";
        private const string m_input_type_name = "input_type";

        private const string m_billing = "billing";

        public string ConfigName { get; set; }

        public void OnGetConfigComplete(string key, IBilling billing)
        {
            var entry = billing.InitParams(
                new KeyValueEntry<string, object> { key = m_order_name, value = OrderCode },
                new KeyValueEntry<string, object> { key = m_amount_name, value = amount },
                new KeyValueEntry<string, object> { key = m_subject_name, value = m_subject },
                new KeyValueEntry<string, object> { key = m_input_type_name, value = m_billing_type },
                new KeyValueEntry<string, object> { key = m_type_name, value = Type },
                new KeyValueEntry<string, object> { key = m_resource_name, value = OrderSource }
                );
            OnComplete(m_billing, entry);
            this.Log(key, Source + m_split + OrderCode + m_split + OrderSource);
        }

        public void OnGetConfigError(string key)
        {
            this.Log(key, Source + m_split + OrderCode + m_split + OrderSource);
        }

        #endregion IGetConfig Billing
    }
}